
<template>
<!-- 创建自定义事件，一旦子组件Student触发了事件就会把值传给App组件 -->
  <div class="app">
    <h1>{{ msg }}，学生姓名是:{{ studentName }}</h1>

    <!-- 通过父组件给子组件传递函数类型的props实现：子给父传递数据 -->
    <School :getSchoolName="getSchoolName" />

    <!--写法1 通过父组件给子组件实例对象绑定一个自定义事件实现（需要子组件emit触发事件，只要事件一触发，就会调用对应的getStudentName函数，也可以接收子组件触发时的参数）（，使用@或v-on） -->
    <!-- <Student @atguigu="getStudentName" @demo="m1"/> -->

    <!-- 写法二（需要配合mounted里面的$on）通过父组件给子组件绑定一个自定义事件实现：子给父传递数据（第二种写法，使用ref） -->
    <Student ref="student" @click.native="show" />
    <!-- 注意，一般不能直接给组件绑定原生的事件，vue会把它当成自定义的事件处理（自定义事件必须得用emit触发），除非你加上.native修饰 -->
  </div>
</template>

<script>
import Student from "./components/Student";
import School from "./components/School";

export default {
  name: "App",
  // 注册子组件School和Student
  components: { School, Student },
  data() {
    return {
      msg: "你好啊！",
      studentName: "",
    };
  },
  methods: {
    //该函数传给子组件，用于子组件向父组件传值
    getSchoolName(name) {
      console.log("App收到了学校名：", name);
    },
    //这里使用了es多参数的写法，这里的params是一个数组，包含剩下的参数
    getStudentName(name, ...params) {
      console.log("App收到了子组件传过来学生名：", name, params);
      this.studentName = name;
      console.log(this);//这里的this是当前vue实例对象，因为是写在methods的普通函数里面的
    },
    m1() {
      console.log("demo事件被触发了！");
    },
    show() {
      alert(123);
    },
  },
  mounted() {
    this.$refs.student.$on("atguigu", this.getStudentName); //给子组件绑定自定义事件,用于接收子组件传过来的值（需要子组件触发事件传递参数再调用对应的getStudentName方法）
    console.log(this);//这里的this，由于事件触发的原因是子组件实例对象
    // this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件（一次性。只触发一次）
  },
};
</script>

<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>
